﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using System.Threading;

namespace Spider
{
    public class DataHandler
    {
        private string queryURLFileName =  @"Data\QueryURL.xml";
        private string productURLFileName =@"Data\ProductURL.xml";
        private string UnParserProURLFileName = @"Data\UnParserProductURL.xml";
        private static DataHandler handler;
        private Rules currentRule = null;

        #region Properites
        public static DataHandler Instance
        {
            get
            {
                if (handler == null)
                    handler = new DataHandler();

                return handler;
            }
        }

        public static void ResetDataHandler()
        {
            handler = null;
        }

        public void ResetCurRule()
        {
            currentRule = null;
        }

        public Rules CurrentRule
        {
            get
            {
                if (currentRule == null)
                {
                    if (Rules.Instance.DicRules.Count == 0)
                        return null;
                    else
                    {
                        /*
                         * 首先，搜索状态为STATUS_QUEUEDING
                           */
                        foreach (Rules rule in Rules.Instance.DicRules.Values)
                        {
                            if (rule.Status.Equals(Convert.ToInt16(Spider.Status.STATUS_QUEUEDING)))
                            {
                                currentRule = rule;
                                return currentRule;
                            }
                        }
                        /*
                            其次,判断所有状态都为STATUS_SUCCESS,将其状态改为STATUS_UNQUEUEDING
                         */
                        bool successTemp = true;
                        foreach (Rules rule in Rules.Instance.DicRules.Values)
                        {
                            if (!rule.Status.Equals(Convert.ToInt16(Spider.Status.STATUS_SUCCESS)))
                            {
                                successTemp = false;
                                break;
                            }
                        }
                        if (successTemp)
                        {
                            foreach (Rules rule in Rules.Instance.DicRules.Values)
                            {
                                rule.Status = Convert.ToInt16(Status.STATUS_UNQUEUEDING);
                                Rules.Instance.ModifyRuleToXMLNotReload(rule);
                            }
                        }
                        /*
                            将第一个状态为STATUS_UNQUEUEDING的网站加载到当前rule,并且把状态改为STATUS_QUEUEDING
                         */
                        foreach (Rules rule in Rules.Instance.DicRules.Values)
                        {
                            if (rule.Status.Equals(Convert.ToInt16(Spider.Status.STATUS_UNQUEUEDING)))
                            {
                                currentRule = rule;
                                rule.Status = Convert.ToInt16(Status.STATUS_QUEUEDING);
                                Rules.Instance.ModifyRuleToXMLNotReload(rule);
                                break;
                            }
                        }
                    }
                }
                return currentRule;
            }
        }

        #endregion


        #region Data Process

        private void SerializationArrayToXML(object[] ListData,string FileName)
        {
            List<string> holders = new List<string>();

            for(int i=0;i<ListData.Length;i++)
            {
                holders.Add(ListData[i].ToString());
            }

            XmlSerializer write = null;
            System.IO.StreamWriter file = null;
            try
            {
                write = new XmlSerializer(holders.GetType());

                file = new System.IO.StreamWriter(FileName);

                write.Serialize(file, holders);
            }
            catch (System.Exception e)
            {
                Log.Instance.WriteException(e);
            }
            finally
            {
                if (file != null)
                    file.Close();
            }
        }

        private void SerializationDicToXML(Dictionary<Uri, Status> Instance, string FileName)
        {
            List<DictionaryHolder> holders = new List<DictionaryHolder>();

            foreach (Uri key in Instance.Keys)
            {
                DictionaryHolder dicHolder = new DictionaryHolder();
                dicHolder.URL = key.ToString();
                dicHolder.URLStaus = Instance[key];
                holders.Add(dicHolder);
            }

            XmlSerializer write = null;
            System.IO.StreamWriter file=null;
            try
            {
                write = new XmlSerializer(holders.GetType());

                file = new System.IO.StreamWriter(FileName);

                write.Serialize(file, holders);
            }
            catch (System.Exception e)
            {
                Log.Instance.WriteException(e);
            }
            finally
            {
                if (file != null)
                    file.Close();
            }
        }

        private Dictionary<Uri, Status> DeserializeXMLToDic(string FileName)
        {
            if (!System.IO.File.Exists(FileName))
                return new Dictionary<Uri, Status>();

            Dictionary<Uri, Status> instance = new Dictionary<Uri, Status>();
            XmlSerializer reader = null;
            System.IO.StreamReader file = null;

            try
            {
                reader = new System.Xml.Serialization.XmlSerializer(typeof(List<DictionaryHolder>));

                file = new System.IO.StreamReader(FileName);

                List<DictionaryHolder> holders = reader.Deserialize(file) as List<DictionaryHolder>;

                foreach (DictionaryHolder holder in holders)
                {
                    instance.Add(new Uri(holder.URL), holder.URLStaus);
                }
            }
            catch (System.Exception e)
            {
                Log.Instance.WriteException(e);
            }
            finally
            {
                if (file != null)
                    file.Close();
            }
            
            return instance;
        }

        public void SaveDicQueryURL(Dictionary<Uri, Status> Instance)
        {
            SerializationDicToXML(Instance, queryURLFileName);
        }

        public void SaveUnParserProductURL(Object[] ListData)
        {
            SerializationArrayToXML(ListData,UnParserProURLFileName);
        }

        public void SaveDicProURL(Dictionary<Uri, Status> Instance)
        {
            SerializationDicToXML(Instance, productURLFileName);
        }

        public Dictionary<Uri, Status> LoadDicQueryURL()
        {
            return DeserializeXMLToDic(queryURLFileName);
        }

        public Dictionary<Uri, Status> LoadDicProURL()
        {
            return DeserializeXMLToDic(productURLFileName);
        }

        public void ClearTempUrl()
        {
            SaveDicProURL(new Dictionary<Uri, Status>());
            SaveDicQueryURL(new Dictionary<Uri, Status>());
            SaveUnParserProductURL(new Object[] { });
        }
        
        #endregion
    }

    public class DictionaryHolder
    {
        public string URL ;
        public Status URLStaus;
    }
}
